﻿using BlogDemo.Common;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Reflection;

namespace BlogDemo.Infrastructure
{
    public abstract class EfConfigurationBase<TEntity> : IEntityTypeConfiguration<TEntity> where TEntity : class, IEntity
    {
        protected readonly string KEY_NAME = "ID";
        protected readonly string EntityKEY = "ID";
        protected string TableName { get; private set; }

        protected PropertyInfo[] EntityProperties { get; private set; }

        public EfConfigurationBase()
        {
            Type tableType = typeof(TEntity);
            TableAttribute tableAttribute = (TableAttribute)tableType.GetCustomAttribute(typeof(TableAttribute));
            TableName = (tableAttribute == null || (tableAttribute != null && string.IsNullOrEmpty(tableAttribute.Name))) ? tableType.Name : tableAttribute.Name;
            EntityProperties = tableType.GetProperties();
            EntityKEY = TableName + KEY_NAME;
        }
        public virtual void Configure(EntityTypeBuilder<TEntity> builder)
        {
            builder.ToTable(this.TableName);
            PropertyInfo propertyInfo = EntityProperties.FirstOrDefault(c => string.Compare(c.Name, KEY_NAME) == 0 || string.Compare(c.Name, EntityKEY ,StringComparison.OrdinalIgnoreCase) == 0);
            if (propertyInfo != null)
            {
                ColumnAttribute column = (ColumnAttribute)propertyInfo.GetCustomAttribute(typeof(ColumnAttribute));
                string id = propertyInfo.IsDefined(typeof(ColumnAttribute)) ? column.Name : propertyInfo.Name;
                builder.HasKey(propertyInfo.Name);
            }
            ConfigureOther(builder);
        }
        public abstract void ConfigureOther(EntityTypeBuilder<TEntity> builder);
    }
    /// <summary>
    /// 有主键的映射
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <typeparam name="TKey"></typeparam>
    public abstract class EfConfigurationBase<TEntity, TKey> : IEntityTypeConfiguration<TEntity>
        where TEntity : class, IEntity<TKey>, IEntity
        where TKey : IComparable<TKey>
    {
        protected readonly string KEY_NAME = "ID";
        protected string TableName { get; private set; }

        protected PropertyInfo[] EntityProperties { get; private set; }

        public EfConfigurationBase()
        {
            Type tableType = typeof(TEntity);
            TableAttribute tableAttribute = (TableAttribute)tableType.GetCustomAttribute(typeof(TableAttribute));
            TableName = (tableAttribute == null || (tableAttribute != null && string.IsNullOrEmpty(tableAttribute.Name))) ? tableType.Name : tableAttribute.Name;
            EntityProperties = tableType.GetProperties();
        }
        public virtual void Configure(EntityTypeBuilder<TEntity> builder)
        {
            builder.ToTable(this.TableName);
            PropertyInfo propertyInfo = EntityProperties.FirstOrDefault(c => string.Compare(c.Name, KEY_NAME) == 0);
            if (propertyInfo != null)
            {
                ColumnAttribute column = (ColumnAttribute)propertyInfo.GetCustomAttribute(typeof(ColumnAttribute));
                string id = propertyInfo.IsDefined(typeof(ColumnAttribute)) ? column.Name : propertyInfo.Name;
                builder.HasKey(propertyInfo.Name);
            } 
            ConfigureOther(builder);
        }
        public abstract void ConfigureOther(EntityTypeBuilder<TEntity> builder);
    }

}
